package com.example.smartpark.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.smartpark.dto.ParkingRecordDTO;
import com.example.smartpark.dto.ParkingRecordQueryDTO;
import com.example.smartpark.exception.BusinessException;
import com.example.smartpark.mapper.ParkingRecordMapper;
import com.example.smartpark.mapper.ParkingSpaceMapper;
import com.example.smartpark.mapper.ReservationMapper;
import com.example.smartpark.mapper.VehicleMapper;
import com.example.smartpark.model.ParkingRecord;
import com.example.smartpark.model.ParkingSpace;
import com.example.smartpark.model.Reservation;
import com.example.smartpark.model.Vehicle;
import com.example.smartpark.service.ParkingRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 停车记录服务实现类
 */
@Slf4j
@Service
public class ParkingRecordServiceImpl extends ServiceImpl<ParkingRecordMapper, ParkingRecord> implements ParkingRecordService {

    @Autowired
    private VehicleMapper vehicleMapper;

    @Autowired
    private ParkingSpaceMapper parkingSpaceMapper;
    
    @Autowired
    private ReservationMapper reservationMapper;

    @Override
    public IPage<ParkingRecordDTO> getParkingRecordPage(ParkingRecordQueryDTO queryDTO) {
        // 构建分页对象
        Page<ParkingRecord> page = new Page<>(queryDTO.getPage(), queryDTO.getSize());

        // 构建查询条件
        LambdaQueryWrapper<ParkingRecord> queryWrapper = new LambdaQueryWrapper<>();
        
        // 如果是查询当前在场车辆，确保exitTime为空且状态为进行中
        if ("current".equals(queryDTO.getType())) {
            queryWrapper.isNull(ParkingRecord::getExitTime)
                       .eq(ParkingRecord::getStatus, 0);
        } else {
            // 其他查询条件
            if (queryDTO.getExitTime() != null) {
                queryWrapper.eq(ParkingRecord::getExitTime, queryDTO.getExitTime());
            }
            
            if (queryDTO.getStatus() != null) {
                queryWrapper.eq(ParkingRecord::getStatus, queryDTO.getStatus());
            }
        }
        
        // 添加其他查询条件
        if (queryDTO.getVehicleIds() != null && !queryDTO.getVehicleIds().isEmpty()) {
            queryWrapper.in(ParkingRecord::getVehicleId, queryDTO.getVehicleIds());
        } else if (queryDTO.getVehicleId() != null) {
            queryWrapper.eq(ParkingRecord::getVehicleId, queryDTO.getVehicleId());
        }
        
        if (queryDTO.getPlateNumber() != null && !queryDTO.getPlateNumber().isEmpty()) {
            // 根据车牌号查询车辆ID
            LambdaQueryWrapper<Vehicle> vehicleQueryWrapper = new LambdaQueryWrapper<>();
            vehicleQueryWrapper.like(Vehicle::getPlateNumber, queryDTO.getPlateNumber());
            Vehicle vehicle = vehicleMapper.selectOne(vehicleQueryWrapper);
            if (vehicle != null) {
                queryWrapper.eq(ParkingRecord::getVehicleId, vehicle.getId());
            } else {
                // 如果没有找到匹配的车牌号，返回空结果
                return new Page<>(queryDTO.getPage(), queryDTO.getSize());
            }
        }
        
        if (queryDTO.getParkingSpaceId() != null) {
            queryWrapper.eq(ParkingRecord::getParkingSpaceId, queryDTO.getParkingSpaceId());
        }
        
        if (queryDTO.getParkingLotId() != null) {
            // 根据停车场ID查询车位ID列表
            LambdaQueryWrapper<ParkingSpace> spaceQueryWrapper = new LambdaQueryWrapper<>();
            spaceQueryWrapper.eq(ParkingSpace::getParkingLotId, queryDTO.getParkingLotId());
            queryWrapper.in(ParkingRecord::getParkingSpaceId, parkingSpaceMapper.selectList(spaceQueryWrapper)
                    .stream().map(ParkingSpace::getId).toArray());
        }
        
        if (queryDTO.getIsPaid() != null) {
            queryWrapper.eq(ParkingRecord::getIsPaid, queryDTO.getIsPaid());
        }
        
        if (queryDTO.getEntryTimeBegin() != null) {
            queryWrapper.ge(ParkingRecord::getEntryTime, queryDTO.getEntryTimeBegin());
        }
        
        if (queryDTO.getEntryTimeEnd() != null) {
            queryWrapper.le(ParkingRecord::getEntryTime, queryDTO.getEntryTimeEnd());
        }
        
        if (queryDTO.getCreatedAtBegin() != null) {
            queryWrapper.ge(ParkingRecord::getCreatedAt, queryDTO.getCreatedAtBegin());
        }
        
        if (queryDTO.getCreatedAtEnd() != null) {
            queryWrapper.le(ParkingRecord::getCreatedAt, queryDTO.getCreatedAtEnd());
        }
        
        // 添加排序条件（按创建时间降序）
        queryWrapper.orderByDesc(ParkingRecord::getCreatedAt);
        
        // 执行分页查询
        IPage<ParkingRecord> recordPage = this.page(page, queryWrapper);
        
        // 转换为DTO
        IPage<ParkingRecordDTO> dtoPage = recordPage.convert(this::convertToDTO);
        
        return dtoPage;
    }

    @Override
    public ParkingRecordDTO getParkingRecordById(Long id) {
        // 查询停车记录
        ParkingRecord record = this.getById(id);
        if (record == null) {
            throw new BusinessException("停车记录不存在");
        }
        
        // 转换为DTO
        return convertToDTO(record);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ParkingRecordDTO createParkingRecord(ParkingRecordDTO parkingRecordDTO) {
        // 验证车辆是否存在
        Vehicle vehicle = vehicleMapper.selectById(parkingRecordDTO.getVehicleId());
        if (vehicle == null) {
            throw new BusinessException("车辆不存在");
        }
        
        // 验证车位是否存在
        ParkingSpace parkingSpace = parkingSpaceMapper.selectById(parkingRecordDTO.getParkingSpaceId());
        if (parkingSpace == null) {
            throw new BusinessException("车位不存在");
        }
        
        // 验证该车辆是否已有进行中的停车记录
        LambdaQueryWrapper<ParkingRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ParkingRecord::getVehicleId, parkingRecordDTO.getVehicleId())
                .eq(ParkingRecord::getStatus, 0); // 0表示进行中
        long count = this.count(queryWrapper);
        if (count > 0) {
            throw new BusinessException("该车辆已有进行中的停车记录");
        }
        
        // 如果有预约ID，验证预约信息
        if (parkingRecordDTO.getReservationId() != null) {
            // 查询预约记录
            Reservation reservation = reservationMapper.selectById(parkingRecordDTO.getReservationId());
            if (reservation == null) {
                throw new BusinessException("预约记录不存在");
            }
            
            // 验证预约状态和支付状态
            if (reservation.getStatus() != 1) {
                throw new BusinessException("预约未确认");
            }
            if (reservation.getIsPaid() != 1) {
                throw new BusinessException("预约费用未支付");
            }
            
            // 验证车辆和车位是否匹配预约记录
            if (!reservation.getVehicleId().equals(parkingRecordDTO.getVehicleId())) {
                throw new BusinessException("车辆与预约不匹配");
            }
            if (!reservation.getParkingSpaceId().equals(parkingRecordDTO.getParkingSpaceId())) {
                throw new BusinessException("车位与预约不匹配");
            }
            
            // 如果是预约车辆，允许使用已预约的车位
            if (parkingSpace.getStatus() != 0 && parkingSpace.getStatus() != 2) {
                throw new BusinessException("车位不可用");
            }
        } else {
            // 非预约车辆，只能使用空闲车位
            if (parkingSpace.getStatus() != 0) {
                throw new BusinessException("车位不可用");
            }
        }
        
        // 创建停车记录
        ParkingRecord record = new ParkingRecord();
        BeanUtils.copyProperties(parkingRecordDTO, record);
        
        // 设置入场时间
        record.setEntryTime(new Date());
        
        // 设置初始状态为进行中
        record.setStatus(0);
        
        // 设置未支付状态
        record.setIsPaid(0);
        
        // 保存停车记录
        this.save(record);
        
        // 更新车位状态为已占用
        parkingSpace.setStatus(1); // 1表示已占用
        parkingSpaceMapper.updateById(parkingSpace);
        
        // 如果是预约入场，更新预约状态为已使用
        if (parkingRecordDTO.getReservationId() != null) {
            Reservation reservation = reservationMapper.selectById(parkingRecordDTO.getReservationId());
            reservation.setStatus(2); // 2表示已使用
            reservationMapper.updateById(reservation);
        }
        
        // 返回DTO
        return convertToDTO(record);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ParkingRecordDTO updateParkingRecord(Long id, ParkingRecordDTO parkingRecordDTO) {
        // 查询停车记录
        ParkingRecord record = this.getById(id);
        if (record == null) {
            throw new BusinessException("停车记录不存在");
        }
        
    
        
        // 设置出场时间
        record.setExitTime(new Date());
        
        // 计算停车费用
        calculateFee(record);
        
        // 设置状态为已完成
        record.setStatus(1); // 1表示已完成
        
        // 更新备注信息
        if (parkingRecordDTO.getRemark() != null) {
            record.setRemark(parkingRecordDTO.getRemark());
        }
        
        // 更新停车记录
        this.updateById(record);
        
        // 更新车位状态为空闲
        ParkingSpace parkingSpace = parkingSpaceMapper.selectById(record.getParkingSpaceId());
        if (parkingSpace != null) {
            parkingSpace.setStatus(0); // 0表示空闲
            parkingSpaceMapper.updateById(parkingSpace);
        }
        
        // 返回DTO
        return convertToDTO(record);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ParkingRecordDTO calculateParkingFee(Long id) {
        // 查询停车记录
        ParkingRecord record = this.getById(id);
        if (record == null) {
            throw new BusinessException("停车记录不存在");
        }
        
        // 计算停车费用
        calculateFee(record);
        
        // 更新停车记录
        this.updateById(record);
        
        // 返回DTO
        return convertToDTO(record);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ParkingRecordDTO updatePaymentStatus(Long id, Integer paymentId) {
        // 查询停车记录
        ParkingRecord record = this.getById(id);
        if (record == null) {
            throw new BusinessException("停车记录不存在");
        }
        
        // 更新支付状态
        record.setIsPaid(1); // 1表示已支付
        record.setPaymentId(paymentId);
        
        // 更新停车记录
        this.updateById(record);
        
        // 返回DTO
        return convertToDTO(record);
    }

    /**
     * 计算停车费用
     *
     * @param record 停车记录
     */
    private void calculateFee(ParkingRecord record) {
        if (record == null || record.getEntryTime() == null) {
            return;
        }

        // 获取当前时间作为临时出场时间
        Date exitTime = record.getExitTime() != null ? record.getExitTime() : new Date();
        
        // 计算停车时长（小时）
        long durationMillis = exitTime.getTime() - record.getEntryTime().getTime();
        double hours = Math.ceil((double) durationMillis / (1000 * 60 * 60));
        
        // 获取费率（假设为每小时10元）
        BigDecimal hourlyRate = new BigDecimal("10.00");
        
        // 计算费用
        BigDecimal fee = hourlyRate.multiply(new BigDecimal(hours));
        record.setParkingFee(fee);
        
        // 如果有出场时间，则更新数据库
        if (record.getExitTime() != null) {
            this.updateById(record);
        }
    }

    /**
     * 将实体转换为DTO
     *
     * @param record 停车记录实体
     * @return 停车记录DTO
     */
    private ParkingRecordDTO convertToDTO(ParkingRecord record) {
        if (record == null) {
            return null;
        }
        
        ParkingRecordDTO dto = new ParkingRecordDTO();
        BeanUtils.copyProperties(record, dto);
        
        // 如果停车费用为空，计算费用
        if (record.getParkingFee() == null || record.getParkingFee().compareTo(BigDecimal.ZERO) == 0) {
            calculateFee(record);
            dto.setParkingFee(record.getParkingFee());
        }
        
        // 获取车辆信息
        Vehicle vehicle = vehicleMapper.selectById(record.getVehicleId());
        if (vehicle != null) {
            dto.setPlateNumber(vehicle.getPlateNumber());
            dto.setVehicleType(vehicle.getVehicleType());
            dto.setVehicleColor(vehicle.getVehicleColor());
        }
        
        // 获取车位信息
        ParkingSpace parkingSpace = parkingSpaceMapper.selectById(record.getParkingSpaceId());
        if (parkingSpace != null) {
            dto.setSpaceNumber(parkingSpace.getSpaceNumber());
            dto.setParkingLotId(parkingSpace.getParkingLotId());
        }
        
        // 设置状态描述
        dto.setStatusDesc(getStatusDesc(record.getStatus()));
        
        return dto;
    }

    /**
     * 获取状态描述
     *
     * @param status 状态码
     * @return 状态描述
     */
    private String getStatusDesc(Integer status) {
        if (status == null) {
            return "未知";
        }
        
        switch (status) {
            case 0:
                return "进行中";
            case 1:
                return "已完成";
            case 2:
                return "异常";
            default:
                return "未知";
        }
    }
} 